package solution;

import java.util.ArrayList;

import hex.*;
import game.*;
import game.GameState.Who;

public class HexPlayer extends GamePlayer {
	private ArrayList<Rope> winPath = new ArrayList<Rope>();
	static Point lastMove = null;
	public static int turnNum = 0;
	
	
	public HexPlayer(String n) {
		super(n, new HexState(), false);
	}
	
	
	public void init() {
		Rope first;
		if(side == Who.HOME)
			first = new Rope(new Point(1, 5), new Point(9, 1));
		else
			first = new Rope(new Point(4, 9), new Point(8,1));
		winPath.add(first);
		System.out.println("1");
	}
	
	/*
	 * @return enum of Who from GameState.java
	 * 	possible values are HOME and AWAY
	 */
	
	
	public Who getWho()
	{ return side; }
	
	
	
	public GameMove getMove(GameState state, String lastMove) {
		if(!lastMove.equals("--"))HexPlayer.lastMove = new Point(lastMove);
		
		
		
		HexState board = (HexState)state;
		HexMove mv = null;
		
		
		
		
		
		for(int i = 0; i < winPath.size(); i++){
			
			if(!winPath.get(i).isClear()){
				
				System.out.println("isclear?");
				Point p = winPath.get(i).nextMove();
				mv = Point.toHexMove(p);
				if(mv.col < 0) //checks for blocked rope (see nextMove() in rope)
					winPath.add(winPath.get(i).cutRope(p));//Cuts p and adds new rope to continue playing
				else
					break; //Point is good, and this move needs to get played to ensure continuity of rope
			}
		}
		System.out.println("4");
		int c = 0;
		System.out.println(mv);
		while((mv == null || mv.row < 0) && c < winPath.size())//Our paths are clear play somewhere in them
		{
			mv = Point.toHexMove(winPath.get(c).moveInside(board));
			c++;
		}
		//If we reach this point in our code and mv is (-1,-1) we can not lose.
		//(If code functions as intended.) Now we just need to fill in our ropes to win.
		if(mv.row < 0)
		{
			for(Rope r : winPath)
			{
				Point p = r.completeRope(board);
				if(p.x >= 0)
					mv = Point.toHexMove(p);
			}
		}
		if(mv.row < 0)
		{
			//Something broke - we quit
			//Plays randomly
			Point po = new Point(((int)(Math.random()*board.N)),((int)(Math.random()*HexState.N)));
			while(!board.moveOK(Point.toHexMove(po)))
				po = new Point(((int)(Math.random()*board.N)),((int)(Math.random()*HexState.N)));
			return Point.toHexMove(po);
		}
		System.out.println("5");
		System.out.println(mv + " Played this");
		return mv;
	}

	public static void main(String [] args) {
		GamePlayer p = new HexPlayer("SEXY BEAST");  // give your player a name here
		p.compete(args, 1);
		
	}
}










class Path{
	static int count = 0;
	ArrayList<Point> allPoints = new ArrayList<Point>();
	public Point myPoint;
	public Path[] subPaths = new Path[6];
	public boolean endPoint = false;
	boolean home;
	
	public Path addPoint(Point p, int i){
		int x = p.x;
		int y = p.y;
		
		if (this.contains(p))return null;
		if (endPoint)return null;
		if (i==0)return null;
		for (Point p2: allPoints)if (p2.equals(p))return null;
		
		int spot = 7;
		if(myPoint.y==y && myPoint.x==x+1)spot = 3-1;
		if (myPoint.y==y && myPoint.x==x-1)spot = 6-1;
		if (myPoint.y==y-1 && myPoint.x==x)spot = 1-1;
		if (myPoint.y==y-1 && myPoint.x==x+1)spot = 2-1;
		if (myPoint.y==y+1 && myPoint.x==x)spot = 4-1;
		if (myPoint.y==y+1 && myPoint.x==x-1)spot = 5-1;
		if (spot!=7){
			subPaths[spot] = new Path(p, home, i-1, allPoints);
			return subPaths[spot];
		}
		return null;
	}

	public boolean contains(Point p){
		if (myPoint.equals(p))return true;
		if (subPaths[0]==null||subPaths[1]==null||subPaths[2]==null||subPaths[3]==null||subPaths[4]==null||subPaths[5]==null)return false;
		for (Path path: subPaths)if (path.contains(p))return true;
		return false;
	}
	
	public Path(Point p, boolean home, int maxMoves, ArrayList<Point> previousPoints){
		this.home = home;
		myPoint = p;
		allPoints.addAll(previousPoints);
		allPoints.add(p);
		
		if (home && p.x==5)endPoint = true;
		if (!home && p.y==5)endPoint = true;
		
		ArrayList<Point> nextOptions = myPoint.getSurrounding();
		System.out.println(count++);
		for (Point n: nextOptions){
			this.addPoint(n, maxMoves);
		}
	}
}